import type { ArrayLength } from "../array";
import type { DistributeUnions } from "../core";
import type { DefaultIfEmpty, RepeatString, ReverseString, TrimLeft, TrimRight } from "../string";
import type { GreatThenOrEquals } from "./compare";
import type { Abs, Negative, NumberToString, SignalPart, DecimalStringToNumber, StringToNumber } from "./core";
import type { IntPart } from "./decimal";

export type IntChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

export type IntChar = IntChars[number];

type IntCharMultiply<C extends IntChar, N extends IntChar> = 
	N extends '0' ? '0' :
	N extends '1' ?
		C :
	N extends '2' ?
		C extends '1' ? '2' :
		C extends '2' ? '4' :
		C extends '3' ? '6' :
		C extends '4' ? '8' :
		C extends '5' ? '01' :
		C extends '6' ? '21' :
		C extends '7' ? '41' :
		C extends '8' ? '61' :
		C extends '9' ? '81' :
		'0':
	N extends '3' ?
		C extends '1' ? '3' :
		C extends '2' ? '6' :
		C extends '3' ? '9' :
		C extends '4' ? '21' :
		C extends '5' ? '51' :
		C extends '6' ? '81' :
		C extends '7' ? '12' :
		C extends '8' ? '42' :
		C extends '9' ? '72' :
		'0':
	N extends '4' ?
		C extends '1' ? '4' :
		C extends '2' ? '8' :
		C extends '3' ? '21' :
		C extends '4' ? '61' :
		C extends '5' ? '02' :
		C extends '6' ? '42' :
		C extends '7' ? '82' :
		C extends '8' ? '23' :
		C extends '9' ? '36' :
		'0':
	N extends '5' ?
		C extends '1' ? '5' :
		C extends '2' ? '01' :
		C extends '3' ? '51' :
		C extends '4' ? '02' :
		C extends '5' ? '52' :
		C extends '6' ? '03' :
		C extends '7' ? '53' :
		C extends '8' ? '04' :
		C extends '9' ? '54' :
		'0':
	N extends '6' ?
		C extends '1' ? '6' :
		C extends '2' ? '21' :
		C extends '3' ? '81' :
		C extends '4' ? '42' :
		C extends '5' ? '03' :
		C extends '6' ? '63' :
		C extends '7' ? '24' :
		C extends '8' ? '84' :
		C extends '9' ? '45' :
		'0':
	N extends '7' ?
		C extends '1' ? '7' :
		C extends '2' ? '41' :
		C extends '3' ? '12' :
		C extends '4' ? '82' :
		C extends '5' ? '53' :
		C extends '6' ? '24' :
		C extends '7' ? '94' :
		C extends '8' ? '65' :
		C extends '9' ? '36' :
		'0':
	N extends '8' ?
		C extends '1' ? '8' :
		C extends '2' ? '61' :
		C extends '3' ? '42' :
		C extends '4' ? '23' :
		C extends '5' ? '04' :
		C extends '6' ? '84' :
		C extends '7' ? '65' :
		C extends '8' ? '46' :
		C extends '9' ? '27' :
		'0':
	N extends '9' ?
		C extends '1' ? '9' :
		C extends '2' ? '81' :
		C extends '3' ? '72' :
		C extends '4' ? '63' :
		C extends '5' ? '54' :
		C extends '6' ? '45' :
		C extends '7' ? '36' :
		C extends '8' ? '27' :
		C extends '9' ? '18' :
		'0':
	never;

type IntCharAdd<C extends IntChar, N extends IntChar = '1'> = 
	N extends '1' ?
		C extends '0' ? '1' :
		C extends '1' ? '2' :
		C extends '2' ? '3' :
		C extends '3' ? '4' :
		C extends '4' ? '5' :
		C extends '5' ? '6' :
		C extends '6' ? '7' :
		C extends '7' ? '8' :
		C extends '8' ? '9' :
		'0' :
	N extends '2' ?
		C extends '0' ? '2' :
		C extends '1' ? '3' :
		C extends '2' ? '4' :
		C extends '3' ? '5' :
		C extends '4' ? '6' :
		C extends '5' ? '7' :
		C extends '6' ? '8' :
		C extends '7' ? '9' :
		C extends '8' ? '0' :
		'1' :
	N extends '3' ?
		C extends '0' ? '3' :
		C extends '1' ? '4' :
		C extends '2' ? '5' :
		C extends '3' ? '6' :
		C extends '4' ? '7' :
		C extends '5' ? '8' :
		C extends '6' ? '9' :
		C extends '7' ? '0' :
		C extends '8' ? '1' :
		'2' :
	N extends '4' ?
		C extends '0' ? '4' :
		C extends '1' ? '5' :
		C extends '2' ? '6' :
		C extends '3' ? '7' :
		C extends '4' ? '8' :
		C extends '5' ? '9' :
		C extends '6' ? '0' :
		C extends '7' ? '1' :
		C extends '8' ? '2' :
		'3' :
	N extends '5' ?
		C extends '0' ? '5' :
		C extends '1' ? '6' :
		C extends '2' ? '7' :
		C extends '3' ? '8' :
		C extends '4' ? '9' :
		C extends '5' ? '0' :
		C extends '6' ? '1' :
		C extends '7' ? '2' :
		C extends '8' ? '3' :
		'4' :
	N extends '6' ?
		C extends '0' ? '6' :
		C extends '1' ? '7' :
		C extends '2' ? '8' :
		C extends '3' ? '9' :
		C extends '4' ? '0' :
		C extends '5' ? '1' :
		C extends '6' ? '2' :
		C extends '7' ? '3' :
		C extends '8' ? '4' :
		'5' :
	N extends '7' ?
		C extends '0' ? '7' :
		C extends '1' ? '8' :
		C extends '2' ? '9' :
		C extends '3' ? '0' :
		C extends '4' ? '1' :
		C extends '5' ? '2' :
		C extends '6' ? '3' :
		C extends '7' ? '4' :
		C extends '8' ? '5' :
		'6' :
	N extends '8' ?
		C extends '0' ? '8' :
		C extends '1' ? '9' :
		C extends '2' ? '0' :
		C extends '3' ? '1' :
		C extends '4' ? '2' :
		C extends '5' ? '3' :
		C extends '6' ? '4' :
		C extends '7' ? '5' :
		C extends '8' ? '6' :
		'7' :
	N extends '9' ?
		C extends '0' ? '9' :
		C extends '1' ? '0' :
		C extends '2' ? '1' :
		C extends '3' ? '2' :
		C extends '4' ? '3' :
		C extends '5' ? '4' :
		C extends '6' ? '5' :
		C extends '7' ? '6' :
		C extends '8' ? '7' :
		'8' :
	C;

type IntCharCarry<C extends IntChar, N extends IntChar, O extends boolean = false> = 
	N extends '1' ?
		O extends true ? 
			C extends '8' | '9' ? true : false :
			C extends '9' ? true : false :
	N extends '2' ?
		O extends true ? 
			C extends '7' | '8' | '9' ? true : false :
			C extends '8' | '9' ? true : false :
	N extends '3' ?
		O extends true ? 
			C extends '6' | '7' | '8' | '9' ? true : false :
			C extends '7' | '8' | '9' ? true : false :
	N extends '4' ?
		O extends true ? 
			C extends '5' | '6' | '7' | '8' | '9' ? true : false :
			C extends '6' | '7' | '8' | '9' ? true : false :
	N extends '5' ?
		O extends true ? 
			C extends '0' | '1' | '2' | '3' ? false : true :
			C extends '0' | '1' | '2' | '3' | '4' ? false : true :
	N extends '6' ?
		O extends true ? 
			C extends '0' | '1' | '2' ? false : true :
			C extends '0' | '1' | '2' | '3' ? false : true :
	N extends '7' ?
		O extends true ? 
			C extends '0' | '1' ? false : true :
			C extends '0' | '1' | '2' ? false : true :
	N extends '8' ?
		O extends true ? 
			C extends '0' ? false : true :
			C extends '0' | '1' ? false : true :
	N extends '9' ?
		O extends true ? true :
			C extends '0' ? false : true :
	O extends true ?
		C extends '9' ? true : false :
		false;

type IntCharMinus<C extends IntChar, N extends IntChar = '1'> = 
	N extends '1' ?
		C extends '9' ? '8' :
		C extends '8' ? '7' :
		C extends '7' ? '6' :
		C extends '6' ? '5' :
		C extends '5' ? '4' :
		C extends '4' ? '3' :
		C extends '3' ? '2' :
		C extends '2' ? '1' :
		C extends '1' ? '0' :
		'9' :
	N extends '2' ?
		C extends '9' ? '7' :
		C extends '8' ? '6' :
		C extends '7' ? '5' :
		C extends '6' ? '4' :
		C extends '5' ? '3' :
		C extends '4' ? '2' :
		C extends '3' ? '1' :
		C extends '2' ? '0' :
		C extends '1' ? '9' :
		'8' :
	N extends '3' ?
		C extends '9' ? '6' :
		C extends '8' ? '5' :
		C extends '7' ? '4' :
		C extends '6' ? '3' :
		C extends '5' ? '2' :
		C extends '4' ? '1' :
		C extends '3' ? '0' :
		C extends '2' ? '9' :
		C extends '1' ? '8' :
		'7' :
	N extends '4' ?
		C extends '9' ? '5' :
		C extends '8' ? '4' :
		C extends '7' ? '3' :
		C extends '6' ? '2' :
		C extends '5' ? '1' :
		C extends '4' ? '0' :
		C extends '3' ? '9' :
		C extends '2' ? '8' :
		C extends '1' ? '7' :
		'6' :
	N extends '5' ?
		C extends '9' ? '4' :
		C extends '8' ? '3' :
		C extends '7' ? '2' :
		C extends '6' ? '1' :
		C extends '5' ? '0' :
		C extends '4' ? '9' :
		C extends '3' ? '8' :
		C extends '2' ? '7' :
		C extends '1' ? '6' :
		'5' :
	N extends '6' ?
		C extends '9' ? '3' :
		C extends '8' ? '2' :
		C extends '7' ? '1' :
		C extends '6' ? '0' :
		C extends '5' ? '9' :
		C extends '4' ? '8' :
		C extends '3' ? '7' :
		C extends '2' ? '6' :
		C extends '1' ? '5' :
		'4' :
	N extends '7' ?
		C extends '9' ? '2' :
		C extends '8' ? '1' :
		C extends '7' ? '0' :
		C extends '6' ? '9' :
		C extends '5' ? '8' :
		C extends '4' ? '7' :
		C extends '3' ? '6' :
		C extends '2' ? '5' :
		C extends '1' ? '4' :
		'3' :
	N extends '8' ?
		C extends '9' ? '1' :
		C extends '8' ? '0' :
		C extends '7' ? '9' :
		C extends '6' ? '8' :
		C extends '5' ? '7' :
		C extends '4' ? '6' :
		C extends '3' ? '5' :
		C extends '2' ? '4' :
		C extends '1' ? '3' :
		'2' :
	N extends '9' ?
		C extends '9' ? '0' :
		C extends '8' ? '9' :
		C extends '7' ? '8' :
		C extends '6' ? '7' :
		C extends '5' ? '6' :
		C extends '4' ? '5' :
		C extends '3' ? '4' :
		C extends '2' ? '3' :
		C extends '1' ? '2' :
		'1' :
	C;
	
type IntCharBorrow<C extends IntChar, N extends IntChar, O extends boolean = false> = 
	N extends '1' ?
		O extends true ? 
			C extends '0' | '1' ? true : false :
			C extends '0' ? true : false :
	N extends '2' ?
		O extends true ? 
			C extends '0' | '1' | '2' ? true : false :
			C extends '0' | '1' ? true : false :
	N extends '3' ?
		O extends true ? 
			C extends '0' | '1' | '2' | '3' ? true : false :
			C extends '0' | '1' | '2' ? true : false :
	N extends '4' ?
		O extends true ? 
			C extends '0' | '1' | '2' | '3' | '4' ? true : false :
			C extends '0' | '1' | '2' | '3' ? true : false :
	N extends '5' ?
		O extends true ? 
			C extends '6' | '7' | '8' | '9' ? false : true :
			C extends '5' | '6' | '7' | '8' | '9' ? false : true :
	N extends '6' ?
		O extends true ? 
			C extends '7' | '8' | '9' ? false : true :
			C extends '6' | '7' | '8' | '9' ? false : true :
	N extends '7' ?
		O extends true ? 
			C extends '8' | '9' ? false : true :
			C extends '7' | '8' | '9' ? false : true :
	N extends '8' ?
		O extends true ? 
			C extends '9' ? false : true :
			C extends '8' | '9' ? false : true :
	N extends '9' ?
		O extends true ? true :
			C extends '9' ? false : true :
	O extends true ?
		C extends '0' ? true : false :
		false;

type AddIntReverseString<A extends string, B extends string, CARRY extends boolean = false> = 
	A extends `${infer AF extends IntChar}${infer AR}` ?
		B extends `${infer BF extends IntChar}${infer BR}` ?
			CARRY extends true ? 
				//进位
				`${IntCharAdd<IntCharAdd<AF, BF>>}${AddIntReverseString<AR, BR, IntCharCarry<AF, BF, CARRY>>}` :
				//不进位
				`${IntCharAdd<AF, BF>}${AddIntReverseString<AR, BR, IntCharCarry<AF, BF>>}` :
		CARRY extends true ?
			`${IntCharAdd<AF>}${AddIntReverseString<AR, '', IntCharCarry<AF, '0', CARRY>>}` :
			`${AF}${AddIntReverseString<AR, ''>}` :
	B extends `${infer BF extends IntChar}${infer BR}` ?
		CARRY extends true ?
			`${IntCharAdd<BF>}${AddIntReverseString<'', BR, IntCharCarry<'0', BF, CARRY>>}` :
			`${BF}${AddIntReverseString<'', BR>}` :
	CARRY extends true ? '1' : '';

type MinusIntReverseString<A extends string, B extends string, BORROW extends boolean = false> =
	A extends `${infer AF extends IntChar}${infer AR}` ?
		B extends `${infer BF extends IntChar}${infer BR}` ?
			BORROW extends true ?
				//借位
				`${IntCharMinus<IntCharMinus<AF, BF>>}${MinusIntReverseString<AR, BR, IntCharBorrow<AF, BF, BORROW>>}` :
				//不借位
				`${IntCharMinus<AF, BF>}${MinusIntReverseString<AR, BR, IntCharBorrow<AF, BF>>}` :
		BORROW extends true ?
			`${IntCharMinus<AF>}${MinusIntReverseString<AR, '', IntCharBorrow<AF, '0', BORROW>>}` :
			`${AF}${MinusIntReverseString<AR, ''>}` :
	B extends `${infer BF extends IntChar}${infer BR}` ?
		BORROW extends true ?
			`${IntCharMinus<BF>}${MinusIntReverseString<'', BR, IntCharBorrow<'0', BF, BORROW>>}` :
			`${BF}${MinusIntReverseString<'', BR>}` :
	BORROW extends true ? never : '';


type MultipyIntReverseString<A extends string, B extends string> = 
	B extends `${infer BF extends IntChar}${infer BR}` ?
		A extends `${infer AF extends IntChar}${infer AR}` ?
			AddIntReverseString<
				AddIntReverseString<
					`${IntCharMultiply<AF, BF>}`,
					`00${MultipyIntReverseString<AR, BR>}`
				>,
				AddIntReverseString<
					`0${MultipyIntReverseString<AF, BR>}`,
					`0${MultipyIntReverseString<BF, AR>}`
				>
			>
		:
			'0'
	:
		'0';

// type r = MultipyIntReverseString<'375893', '65894038'> 
type r = MultipyIntReverseString<'375893', '6'>

/**
 * @zh 是否是整数.
 * 不能用于判断联合类型
 * @en Are integers.
 * Cannot be used to determine union types
 * @example IsInt<123> // true
 * @example IsInt<123.1> // false
 */
export type IsInt<T extends number> = NumberToString<T> extends `${number | '' | '-'}.${infer D extends number}` ? D extends 0 ? true : false : true;

/**
 * @zh 只能是整数.
 * 不能处理联合类型
 * @en Only integers.
 * Cannot handle union types
 * @example AsInt<123> // 123
 * @example AsInt<123.1> // never
 */
export type AsInt<T extends number> = IsInt<T> extends true ? T : never;

/**
 * @zh 是否是非负整数.
 * 不能用于判断联合类型
 * @en Are non-negative integers.
 * Cannot be used to determine union types
 * @example IsUInt<123> // true
 * @example IsUInt<-123> // false
 * @example IsUInt<123.1> // false
 */
export type IsUInt<T extends number> = NumberToString<T> extends `-${number}` ? false : IsInt<T>;

/**
 * @zh 只能是非负整数.
 * 不能处理联合类型
 * @en Only non-negative integers.
 * Cannot handle union types
 * @example AsUInt<123> // 123
 * @example AsUInt<-123> // never
 * @example AsUInt<123.1> // never
 */
export type AsUInt<T extends number> = IsUInt<T> extends true ? T : never;

export type SimpleIntEnumerate<N extends number, Acc extends number[] = []> =
	IsUInt<N> extends true ?
		Acc['length'] extends N ? Acc[number] : 
		SimpleIntEnumerate<N, [...Acc, Acc['length']]> :
		never;

/**
 * @zh 索引序列.
 * 创建一个从 0 到 N 的数字序列类型,等效于: 0 | 1 | 2 | 3 | ... | N - 1
 * @en Create a number sequence type from 0 to N.
 * Equivalent to: 0 | 1 | 2 | 3 | ... | N - 1
 * @param N 数量(非负整数,非联合类型) count(non-negative integer, non-union type)
 * @example IntEnumerate<5> // 0 | 1 | 2 | 3 | 4
 * @example IntEnumerate<0> // never
 * @example IntEnumerate<-1> // never
 * @example IntEnumerate<1.1> // never
 */
export type IntEnumerate<N extends number> = 
    DistributeUnions<[N]> extends [infer Ni extends N] ? Ni extends Ni ? SimpleIntEnumerate<Ni> : never : never;

/**
 * @zh 数字序列.
 * 创建一个从 F 到 N 的数字序列类型, 等效于: F | F + 1 | F + 2 | .... | N - 1
 * @en Create a number sequence type from F to N.
 * Equivalent to: F | F + 1 | F + 2 | .... | N - 1
 * @param F 起始数字(非负整数,非联合类型) start(non-negative integer, non-union type)
 * @param N 结束数字(非负整数,非联合类型) end(non-negative integer, non-union type)
 * @example IntRange<0, 3> // 0 | 1 | 2
 * @example IntRange<3, 5> // 3 | 4
 * @example IntRange<5, 5> // never
 * @example IntRange<5, 3> // never
 * @example IntRange<-5, 5> // never
 */
export type IntRange<F extends number, T extends number> =
	IsUInt<F> extends true ?
		IsUInt<T> extends true ?
			Exclude<IntEnumerate<T>, IntEnumerate<F>> :
		never :
	never;

type SimpleAddOne<N extends number> = IsUInt<N> extends true ? 
	ReverseString<NumberToString<N>> extends `${infer F extends IntChar}${infer Rest}` ? 
		F extends '8' ? DecimalStringToNumber<`${ReverseString<Rest>}9`> :
		F extends '7' ? DecimalStringToNumber<`${ReverseString<Rest>}8`> :
		F extends '6' ? DecimalStringToNumber<`${ReverseString<Rest>}7`> :
		F extends '5' ? DecimalStringToNumber<`${ReverseString<Rest>}6`> :
		F extends '4' ? DecimalStringToNumber<`${ReverseString<Rest>}5`> :
		F extends '3' ? DecimalStringToNumber<`${ReverseString<Rest>}4`> :
		F extends '2' ? DecimalStringToNumber<`${ReverseString<Rest>}3`> :
		F extends '1' ? DecimalStringToNumber<`${ReverseString<Rest>}2`> :
		F extends '0' ? DecimalStringToNumber<`${ReverseString<Rest>}1`> :
		Rest extends '' ? 10 : DecimalStringToNumber<`${SimpleAddOne<DecimalStringToNumber<ReverseString<Rest>>>}0`> : 
		0:
	never

/**
 * @zh 整数加一.
 * 指定整数+1后的数字类型
 * @en Create a number type after adding 1 to an integer
 * @param N 待+1数字类型(非负整数,非联合类型) The number to add one(non-negative integer, non-union type)
 * @example AddOne<0> // 1
 * @example AddOne<1> // 2
 * @example AddOne<-1> // never
 * @example AddOne<1.2> // never
 */
export type AddOne<N extends number> = 
    DistributeUnions<[N]> extends [infer Ni extends N] ? Ni extends Ni ? SimpleAddOne<Ni> : never : never;

type SimplMinusOne<N extends number> = IsUInt<N> extends true ? 
	N extends 0 ? never :
		ReverseString<NumberToString<N>> extends `${infer F extends IntChar}${infer Rest}` ? 
			F extends '1' ? DecimalStringToNumber<`${ReverseString<Rest>}0`> :
			F extends '2' ? DecimalStringToNumber<`${ReverseString<Rest>}1`> :
			F extends '3' ? DecimalStringToNumber<`${ReverseString<Rest>}2`> :
			F extends '4' ? DecimalStringToNumber<`${ReverseString<Rest>}3`> :
			F extends '5' ? DecimalStringToNumber<`${ReverseString<Rest>}4`> :
			F extends '6' ? DecimalStringToNumber<`${ReverseString<Rest>}5`> :
			F extends '7' ? DecimalStringToNumber<`${ReverseString<Rest>}6`> :
			F extends '8' ? DecimalStringToNumber<`${ReverseString<Rest>}7`> :
			F extends '9' ? DecimalStringToNumber<`${ReverseString<Rest>}8`> :
			Rest extends '1' ? 9 : DecimalStringToNumber<`${SimplMinusOne<DecimalStringToNumber<ReverseString<Rest>>>}9`> : 
			0:
	never;

/**
 * @zh 整数减一.
 * 指定整数-1后的数字类型
 * @en Create a type that subtracts one from a number.
 * @param N 待-1数字类型(正整数,非联合类型) The number to add one(positive integer, non-union type)
 * @example MinusOne<1> // 0
 * @example MinusOne<10> // 9
 * @example MinusOne<0> // never
 * @example MinusOne<1.5> // never
 */
export type MinusOne<N extends number> =
    DistributeUnions<[N]> extends [infer Ni extends N] ? Ni extends Ni ? SimplMinusOne<Ni> : never : never;

	
type SimpleIntList<S extends number, L extends number, A extends number[] = []> = 
	IsUInt<S> extends true ?
		IsUInt<L> extends true ?
			number extends L ? number : A['length'] extends L ? A[number] : SimpleIntList<AddOne<S>, L, [...A, S]> :
		never :
	never;

/**
 * @zh 数字序列.
 * 创建一个从 S 开始的指定数量 L 的数字序列类型, 等效于: F | F + 1 | F + 2 | .... | F + L - 1
 * @en Create a number sequence type from S and with length L, equivalent to: F | F + 1 | F + 2 | .... | F + L - 1
 * @param S 起始数字(非负整数,非联合类型) start(non-negative integer, non-union type)
 * @param L 序列数量(非负整数,非联合类型) length(non-negative integer, non-union type)
 * @example IntList<0, 3> // 0 | 1 | 2
 * @example IntList<3, 5> // 3 | 4 | 5 | 6 | 7 
 * @example IntList<5, 3> // 5 | 6 | 7
 * @example IntList<-5, 5> // never
 */
export type IntList<S extends number, L extends number> = 
	SimpleIntList<S, L>;

/**
 * @zh 求和.
 * 两个整数的和
 * @en Sum of two integers
 * @param A - 待求和的整数
 * @param B - 待求和的整数
 * @example AddInt<0, 0> // 0
 * @example AddInt<10, 20> // 30
 * @example AddInt<5, 550> // 555
 */
export type AddInt<A extends number, B extends number> = 
	SignalPart<A> extends 1 ?
		SignalPart<B> extends 1 ?
			//正常求和
			DecimalStringToNumber<ReverseString<AddIntReverseString<ReverseString<NumberToString<IntPart<A>>>, ReverseString<NumberToString<IntPart<B>>>>>> :
			MinusInt<A, Abs<B>> :
		SignalPart<B> extends 1 ?
			MinusInt<B, Abs<A>> :
			Negative<AddInt<Abs<A>, Abs<B>>>;

/**
 * @zh 求差.
 * 两个整数的差
 * @en Minus of two integers
 * @param A - 被减数
 * @param B - 减数
 * @example MinusInt<0, 0> // 0
 * @example MinusInt<10, 20> // -10
 * @example MinusInt<550, 5> // 545
 */
export type MinusInt<A extends number, B extends number> = 
	SignalPart<A> extends 1 ?
		SignalPart<B> extends 1 ?
			GreatThenOrEquals<A, B> extends true ?
				//正常求差
				DecimalStringToNumber<ReverseString<DefaultIfEmpty<TrimRight<MinusIntReverseString<ReverseString<NumberToString<IntPart<A>>>, ReverseString<NumberToString<IntPart<B>>>>, '0'>, '0'>>> :
				Negative<MinusInt<B, A>> : 
			AddInt<A, Abs<B>> :
		SignalPart<B> extends 1 ?
			Negative<AddInt<Abs<A>, B>> :
			MinusInt<Abs<B>, Abs<A>>;


/**
 * @zh 求积.
 * 两个整数的积
 * @en Multipy of two integers
 * @param A - 乘数
 * @param B - 另一个乘数
 * @example MultipyInt<0, 0> // 0
 * @example MultipyInt<10, 20> // 200
 * @example MultipyInt<550, 5> // 2750
 */
export type MultipyInt<A extends number, B extends number> = 
	SignalPart<A> extends SignalPart<B> ?
		//正常求差
		DecimalStringToNumber<ReverseString<DefaultIfEmpty<TrimRight<MultipyIntReverseString<ReverseString<NumberToString<IntPart<Abs<A>>>>, ReverseString<NumberToString<IntPart<Abs<B>>>>>, '0'>, '0'>>> :
		Negative<MultipyInt<Abs<A>, Abs<B>>>;

type SimpleDivideInt<A extends number, B extends number, D extends unknown[] = []> = 
	GreatThenOrEquals<A, B> extends true ? 
		SimpleDivideInt<MinusInt<A, B>, B, [...D, unknown]> :
		[ArrayLength<D>, A];

type DivideIntString<A extends string, B extends number, F extends string = ''> =
	B extends 0 ? never : 
	A extends `${F}${infer C}${infer R}` ?
		SimpleDivideInt<DecimalStringToNumber<`${F}${C}`>, B> extends [infer D extends number, infer M extends number] ?
			M extends 0 ?
				DivideIntString<`${R}`, B> extends [infer DS extends string, infer DM extends number] ?
					[`${D}${DS}`, DM] : never :
				DivideIntString<`${M}${R}`, B, NumberToString<M>> extends [infer DS extends string, infer DM extends number] ?
					[`${D}${DS}`, DM] : never : 
		never :
	A extends '' ? ['', 0] : ['', DecimalStringToNumber<A>];

/**
 * @zh 求商.
 * 两个整数的商
 * @en Divide of two integers
 * @param A - 被除数
 * @param B - 除数
 * @example DivideInt<0, 0> // never
 * @example DivideInt<10, 20> // 0
 * @example DivideInt<550, 5> // 110
 * @example DivideInt<550, 45> // 12
 */
export type DivideInt<A extends number, B extends number> =
	B extends 0 ? never : 
	DivideIntString<NumberToString<A>, B> extends [infer D extends string, number] ?
		DecimalStringToNumber<TrimLeft<D, '0'>> : never;

/**
 * @zh 求余.
 * 两个整数的余
 * @en Mod of two integers
 * @param A - 被除数
 * @param B - 除数
 * @example ModInt<0, 0> // never
 * @example ModInt<10, 20> // 10
 * @example ModInt<550, 5> // 0
 * @example ModInt<550, 45> // 10
 */
export type ModInt<A extends number, B extends number> =
	B extends 0 ? never : 
	DivideIntString<NumberToString<A>, B> extends [string, infer M extends number] ?
		M : never;